/*
Metronom for Android
    Copyright (C) 2012  Zdeněk Janeček <jan.zdenek@gmail.com>

	Contributors: Jiří Janeček

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package kiv.janecekz;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.text.method.LinkMovementMethod;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.quietlycoding.android.picker.NumberPicker;
import com.quietlycoding.android.picker.NumberPicker.OnChangedListener;

public class Main extends Activity implements OnSharedPreferenceChangeListener {
	private Operator op;
	private Peeper peeper;
	private Tempomat tempo;
	private SeekBar seekBar;
	private NumberPicker beatPicker;
	private NumberPicker bpmPicker;
	private PowerManager.WakeLock wl;
	private AlertDialog helpDialog;
	private ObserversUpdater ou;
	private View main;

	// for debugging
	public static final String TAG = "Metronom";

	private static final int HELLO_ID = 1;
	private Notification notification;
	private NotificationManager mNotificationManager;
	private Anim anim;

	/**
	 * Main initialization of all Views and Events.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		main = (View) findViewById(R.id.main);
		View clickSpace = (View) findViewById(R.id.relativeLayout);
		changeBg();
		
		setVolumeControlStream(AudioManager.STREAM_MUSIC);

		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Beep");

		// Notification
		String ns = Context.NOTIFICATION_SERVICE;
		mNotificationManager = (NotificationManager) getSystemService(ns);

		ImageView image = (ImageView) findViewById(R.id.sun);
		Animation bFaIn = AnimationUtils.loadAnimation(this, R.anim.blink);
		Animation bFaOut = AnimationUtils.loadAnimation(this, R.anim.blank);
		Animation faIn = AnimationUtils.loadAnimation(this, R.anim.lowblink);
		Animation faOut = AnimationUtils.loadAnimation(this, R.anim.lowblank);
		anim = new Anim(image, bFaIn, bFaOut, faIn, faOut);

		peeper = new Peeper(getApplicationContext(), anim);
		changeSound();

		ou = new ObserversUpdater();
		beatPicker = (NumberPicker) findViewById(R.id.beatCount);
		bpmPicker = (NumberPicker) findViewById(R.id.bpmCount);

		seekBar = (SeekBar) findViewById(R.id.seekBar1);
		seekBar.setMax(Tempomat.MAX_BPM - Tempomat.MIN_BPM);

		bpmPicker.setRange(Tempomat.MIN_BPM, Tempomat.MAX_BPM);
		bpmPicker.setCurrent(SharedPref.getBPM(getApplicationContext()));
		beatPicker.setRange(1, 4);
		beatPicker.setCurrent(SharedPref.getTime(getApplicationContext()));

		clickSpace.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				// Perform action on clicks
				Context con = getApplicationContext();
				SharedPref.setPlay(con, !SharedPref.getPlay(con));
				if (SharedPref.getPlay(con)) {
					op.setPlay(true);
				} else {
					op.setPlay(false);
				}
			}
		});

		// SeekBar
		seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// Nothing to do
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// Nothing to do
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				if (fromUser) {
					tempo.setBPM(progress + Tempomat.MIN_BPM);
				}
			}
		});

		// Tempo picker
		beatPicker.setOnChangeListener(new OnChangedListener() {

			@Override
			public void onChanged(NumberPicker picker, int oldVal, int newVal) {
				peeper.setTime(newVal);
			}
		});

		// Výběr
		bpmPicker.setOnChangeListener(new OnChangedListener() {

			@Override
			public void onChanged(NumberPicker picker, int oldVal, int newVal) {
				tempo.setBPM(newVal);
			}
		});

		SharedPreferences sp = getSharedPreferences(SharedPref.PREFS_NAME,
				MODE_PRIVATE);
		sp.registerOnSharedPreferenceChangeListener(this);

		ou.addView(bpmPicker);
		ou.addView(seekBar);

		tempo = new Tempomat(getApplicationContext());

		tempo.addObserver(ou);

		// Help menu
		AlertDialog.Builder help = new AlertDialog.Builder(Main.this);
		help.setTitle(R.string.help);
		help.setMessage(R.string.helpText);
		help.setIcon(android.R.drawable.ic_menu_info_details);
		helpDialog = help.create();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);

		Intent prefsIntent = new Intent(getApplicationContext(), Setup.class);

		menu.findItem(R.id.set).setIntent(prefsIntent);

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.help:
			helpDialog.show();
			((TextView) helpDialog.findViewById(android.R.id.message))
					.setMovementMethod(LinkMovementMethod.getInstance());
			return true;

		case R.id.set:
			startActivity(item.getIntent());
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (!wl.isHeld() || this.isFinishing()) {
			op.interrupt();
			tempo.deleteObserver(op);
		}

		if (SharedPref.getNotify(getApplicationContext())
				&& (!this.isFinishing())) {
			int icon = R.drawable.ic_launcher;
			CharSequence tickerText = getString(R.string.nTicker);
			long when = System.currentTimeMillis();

			notification = new Notification(icon, tickerText, when);

			Context context = getApplicationContext();
			Intent notificationIntent = new Intent(context, Main.class);
			notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
					| Intent.FLAG_ACTIVITY_SINGLE_TOP);
			PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
					notificationIntent, HELLO_ID);

			CharSequence contentTitle = getString(R.string.app_name);
			CharSequence contentText = getString(R.string.nText);
			notification.setLatestEventInfo(this, contentTitle, contentText,
					contentIntent);

			mNotificationManager.notify(HELLO_ID, notification);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		mNotificationManager.cancel(HELLO_ID);
		if (!wl.isHeld()) {
			op = new Operator(peeper, wl);
			tempo.addObserver(op);

			tempo.refreshObservers();

			op.start();
			if (SharedPref.getPlay(getApplicationContext())) {
				op.setPlay(true);
			}
		}
	}

	@Override
	protected void onDestroy() {
		op.interrupt();
		peeper.cleanup();
		super.onDestroy();
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		
		if (key.equals(getString(R.string.pref_key_bg))) {
			changeBg();
		}

		if (key.equals(getString(R.string.pref_key_sound))) {
			changeSound();
		}
	}
	
	private void changeBg() {
		switch (SharedPref.getTheme(getApplicationContext())) {
		case 0:
			main.setBackgroundResource(R.drawable.bg_morning);
			break;
		case 1:
			main.setBackgroundResource(R.drawable.bg_sunset);
			break;
		case 2:
			main.setBackgroundResource(R.drawable.bg_night);
			break;

		default:
			break;
		}
	}
	private void changeSound() {
		int value = SharedPref.getSound(getApplicationContext());
		switch (value) {
		case 0:
		case 1:
			peeper.setSound((byte) value);
			break;
		default:
			break;
		}
	}
}